#include "dev_multi_button.h"
#include <string.h>

/**
 * @brief 按键监视函数
 * @param pstDevice 设备句柄
 * @param pstBtn 按键设备结构体
 * @return @see DEV_RET
 */
static Dev_Ret_t
dev_mul_btn_monitor(Device_t* pstDevice, Dev_Multi_Button_t *pstBtn)
{
    // 按键心跳计数
    pstBtn->SW.u8Tick++;
    
    // 判断是否被按下过 -- 按下时间>0时标记为按钮曾被按下
    uint8_t u8IsPressed = (pstBtn->SW.u8PressedTick > 0);
    
    // 读取按键状态
    uint8_t u8NowState = pstBtn->HW.pfnRead();

    // 判断按键状态是否发生变化
    if(pstBtn->SW.u8State != u8NowState)
    {
        // 更新状态
        pstBtn->SW.u8State = u8NowState;

        // 判断按键是否按下
        if(pstBtn->SW.u8State == pstBtn->SW.u8Active) {

            // 首次按键按下，重置心跳计数
            if(pstBtn->SW.u8PressedTick == 0) pstBtn->SW.u8Tick = 1;

            // 按键按下心跳计数
            pstBtn->SW.u8PressedTick++;
        }
        else {
            // 按键松开，按键次数+1
            if(u8IsPressed) pstBtn->SW.u8Count++;

            // 多次按下，计数器清零
            if(pstBtn->SW.u8Count > 1) pstBtn->SW.u8PressedTick = 0;
        }
    }
    else if(u8NowState == pstBtn->SW.u8Active && u8IsPressed)
    {
        // 被按下过，且按键状态未发生改变，但持续按下状态，按下时间 +1
        pstBtn->SW.u8PressedTick++;
    }

    // 判断心跳是否超时
    if(pstBtn->SW.u8Tick >= pstBtn->SW.u8Interval)
    {
        // 判断是否有事件发生
        if(pstBtn->SW.u8Count > 1)
        {
            // 多击事件发生
            DEV_EMIT_EVENT(pstDevice, BTN_EVT_MULTI_CLICKED);
            return DEV_OK;
        }
        else if(pstBtn->SW.u8Count == 0)
        {
            if(pstBtn->SW.u8PressedTick >= pstBtn->SW.u8Interval) 
            {
                // 长按事件发生
                DEV_EMIT_EVENT(pstDevice, BTN_EVT_LONG_CLICKED);
                return DEV_OK;
            }
        }
        else 
        {
            if(pstBtn->SW.u8PressedTick < pstBtn->SW.u8ShortTh)
            {
                // 单击事件发生
                DEV_EMIT_EVENT(pstDevice, BTN_EVT_SINGLE_CLICKED);
                return DEV_OK;
            }
            else 
            {
                // 短按事件发生
                DEV_EMIT_EVENT(pstDevice, BTN_EVT_SHORT_CLICKED);
                return DEV_OK;
            }
        }

        // 重置心跳计数
        pstBtn->SW.u8Tick = 0;

        // 重置当前按下时间
        pstBtn->SW.u8PressedTick = 0;

        // 重置按键次数
        pstBtn->SW.u8Count = 0;
    }

    // 设备正常
    return DEV_OK;
}

/**
 * @brief 按键设备控制函数
 * @param pstDevice 设备句柄
 * @param u8Cmd 命令
 * @param pvArg 参数
 * @return @see DEV_RET
 */
Dev_Ret_t
dev_mul_btn_ioctl(Device_t *pstDevice, uint8_t u8Cmd, void *pvArg)
{
    (void) pvArg;

    // 转换为Dev_Input_t结构体
    Dev_Multi_Button_t *pstBtn = GET_CONTEXT(pstDevice, Dev_Multi_Button_t);

    // 接口为空
    if(NULL == pstBtn->HW.pfnRead) 
    {
        return DEV_INTERFACE_NULL;
    }

    // 执行命令
    switch(u8Cmd)
    {
        case BTN_CMD_MONITOR:
        {
            // 监视输入
            return dev_mul_btn_monitor(pstDevice, pstBtn);
        }

        default:
        {
            // 未知命令
            return DEV_UNKNOWN_IOCTL;
        }
    }
}
